using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework;

namespace WPCoco.Particles
{
    public static class ParticleSystemRenderer
    {
        static ParticleSystemRenderer()
        {
            defaultState = new ParticleSystemRendererState();
        }

        class ParticleSystemRendererState : IGraphicState
        {
            SamplerState sampler;
            public SamplerState Sampler
            {
                get { return sampler; }
                set { sampler = value; }
            }

            DepthStencilState depthStencil;
            public DepthStencilState DepthStencil
            {
                get { return depthStencil; }
                set { depthStencil = value; }
            }

            BlendState blend;
            public BlendState Blend
            {
                get { return blend; }
                set { blend = value; }
            }

            RasterizerState rasterizer;
            public RasterizerState Rasterizer
            {
                get { return rasterizer; }
                set { rasterizer = value; }
            }
        }

        static ParticleSystemRendererState defaultState;

        public static void Render(ParticleSystem system, Matrix worldMatrix)
        {
            defaultState.Blend = system.IsAdditive ? BlendState.Additive : BlendState.AlphaBlend;
            Render(system, defaultState, worldMatrix);
        }

        public static void Render(ParticleSystem system, IGraphicState state, Matrix worldMatrix)
        {
            CachedSpriteBatch batch = SpriteBatchCache.GetVolatile();
            batch.Begin(SpriteSortMode.Deferred, state.Blend, state.Sampler, state.DepthStencil, state.Rasterizer, null, worldMatrix);
            Render(system, batch);
            batch.End();
        }

        public static void Render(ParticleSystem system, SpriteBatch batch)
        {
            Texture2D texture = system.GetTexture();
            if (texture == null) return;

            LinkedListNode<Particle> piv = system.Particles.First;

            Vector2 origin = new Vector2(texture.Width / 2, texture.Height / 2);

            bool pmc = system.NonPremultiplied;

            while (piv != null)
            {
                Particle p = piv.Value;

                Color color;
                if (!pmc)
                    color = Color.FromNonPremultiplied(p.Color);
                else
                    color = new Color(p.Color);

                float scale = 1.0f;
                if (texture.Width > texture.Height)
                    scale = p.Size / texture.Height;
                else
                    scale = p.Size / texture.Width;

                batch.Draw(texture, p.Position, null, color, p.Rotation, origin, scale, SpriteEffects.None, 0);

                piv = piv.Next;
            }
        }

    }
}
